#!/bin/bash -x

test_pod_dir="$HOME/workspace/pod-workload"

base_image_name="busybox:latest"
base_image_uri=""
signed_image_name="busybox-signed:latest"
signed_image_uri=""

registry_ip_addr=""
registry_port=31313
registry=""

pod_yaml="${test_pod_dir}/signed-image-pod.yaml"
pod_name="busybox"
pod_runtimeclass="kata-qemu-csv"
pod_container_image_uri=""

usage () {
  set +x
  echo -e "\033[31m
Usage: $0 <-h|<-i <registry-ip-addr>> [-p <registry-port>] [-r <kata-coco-runtimeclass>]

       -h,--help         Display this help message
       -i,--ip           The ip address of the local registry
       -p,--port         The port number of the local registry
       -r,--runtimeclass Specify the runtimeclass
                         Valid value are shown as following:
                             kata-qemu-coco-dev
                             kata-qemu-csv
                             kata-qemu-csv2
                             kata-qemu-csv3
                         Default is kata-qemu-csv
\033[0m"
  set -x
}

params=$(getopt -o hi:p:r:C: --long help,ip:,port:,runtimeclass: -- "$@")
if [ $? -ne 0 ]; then
  echo "[Error] cannot parse parameters"
  exit 1
fi

eval set -- "$params"

while true; do
  case "$1" in
  -h|--help)
    usage
    exit 0
    ;;
  -i|--ip)
    registry_ip_addr="$2"
    shift 2
    ;;
  -p|--port)
    registry_port="$2"
    shift 2
    ;;
  -r|--runtimeclass)
    pod_runtimeclass="$2"
    shift 2
    ;;
  --)
    shift
    break
    ;;
  *)
    usage
    exit 1
    ;;
  esac
done

if [ "X${registry_ip_addr}" = "X" ]; then
  usage
  exit 1
fi

registry="${registry_ip_addr}:${registry_port}"
base_image_uri="${registry}/${base_image_name}"
signed_image_uri="${registry}/${signed_image_name}"
pod_container_image_uri="${signed_image_uri}"



export COSIGN_PASSWORD="just1testing2password3"
cosign_bin=$(which cosign)
cosign_output_dir="${test_pod_dir}/image_signing/"
cosign_pubkey="${cosign_output_dir}/cosign.pub"
cosign_privkey="${cosign_output_dir}/cosign.key"
cosign_security_policy_json="${cosign_output_dir}/security-sig-policy.json"

kbs_namespace="trustee-operator-system"
kbs_deployment="trustee-deployment"
kbs_ip_addr="$(kubectl get pods -n ${kbs_namespace} -o wide | \
  grep ${kbs_deployment} | \
  sed "s/^.* \([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\) .*$/\1/g")"
kbs_resource_path="/opt/confidential-containers/kbs/repository"
kbs_key_path="default/cosign-key/1"
kbs_key_id="kbs:///${kbs_key_path}"
kbs_security_policy_path="default/security-policy/test"

generate_image_signing_key () {
  echo "[Generate image signing key]"
  if [ ! -d ${cosign_output_dir} ]; then
    mkdir -p ${cosign_output_dir} || true
  fi
  if [ ! -e ${cosign_privkey} ]; then
    pushd ${cosign_output_dir}
    ${cosign_bin} generate-key-pair
    popd # ${cosign_output_dir}
  else
    echo "[  Use already existing cosign keypair]"
  fi
}

generate_image_signing_key

build_signed_image () {
  echo "[Build signed image based on base image]"

  local docker_build_arg_https_proxy=""
  local docker_build_arg_http_proxy=""

  if [ "X${https_proxy}" != "X" ]; then
    docker_build_arg_https_proxy="--build-arg HTTPS_PROXY=${https_proxy}"
  elif [ "X${HTTPS_PROXY}" != "X" ]; then
    docker_build_arg_https_proxy="--build-arg HTTPS_PROXY=${HTTPS_PROXY}"
  fi
  if [ "X${http_proxy}" != "X" ]; then
    docker_build_arg_http_proxy="--build-arg HTTP_PROXY=${http_proxy}"
  elif [ "X${HTTP_PROXY}" != "X" ]; then
    docker_build_arg_http_proxy="--build-arg HTTP_PROXY=${HTTP_PROXY}"
  fi

  docker build \
    ${docker_build_arg_https_proxy} \
    ${docker_build_arg_http_proxy} \
    -t ${signed_image_uri} - <<EOF
FROM ${base_image_uri}
CMD [ "/bin/sh", "-c", "echo 'Signed image test SUCCESS :)'; sleep 1d"]
EOF

  docker push ${signed_image_uri}
  ${cosign_bin} sign --key ${cosign_privkey} \
    ${signed_image_uri}
}

build_signed_image

upload_image_signing_info_to_kbs () {
  echo "[Upload image signing info to kbs]"

  echo "[  Upload image signing key to kbs]"
  kubectl exec deploy/${kbs_deployment} -n ${kbs_namespace} \
    -c kbs \
    -- mkdir -p "${kbs_resource_path}/$(dirname "${kbs_key_path}")"
  cat "${cosign_pubkey}" | \
    kubectl exec -i deploy/${kbs_deployment} -n ${kbs_namespace} \
    -c kbs \
    -- tee "${kbs_resource_path}/${kbs_key_path}" > /dev/null

  echo "[  Upload security signing policy to kbs]"
  cat <<EOF | tee ${cosign_security_policy_json}
{
    "default": [{"type": "reject"}],
    "transports": {
        "docker": {
            "${signed_image_uri}": [
                {
                    "type": "sigstoreSigned",
                    "keyPath": "kbs:///${kbs_key_path}"
                }
            ]
        }
    }
}
EOF
  kubectl exec deploy/${kbs_deployment} -n ${kbs_namespace} \
    -c kbs \
    -- mkdir -p "${kbs_resource_path}/$(dirname ${kbs_security_policy_path})"
  cat ${cosign_security_policy_json} | \
    kubectl exec -i deploy/${kbs_deployment} -n ${kbs_namespace} \
    -c kbs \
    -- tee "${kbs_resource_path}/${kbs_security_policy_path}"
}

upload_image_signing_info_to_kbs

generate_pod_yaml () {
  echo "[Generate Pod yaml]"

  if [ ! -d $(dirname ${pod_yaml}) ]; then
    mkdir -p $(dirname ${pod_yaml})
  fi

  cat <<EOF | tee ${pod_yaml}
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: ${pod_name}
  name: signed-${pod_name}
  annotations:
    io.containerd.cri.runtime-handler: ${pod_runtimeclass}
    io.katacontainers.config.hypervisor.kernel_params: "agent.enable_signature_verification=true agent.image_policy_file=kbs:///${kbs_security_policy_path} agent.guest_components_rest_api=resource agent.aa_kbc_params=cc_kbc::http://${kbs_ip_addr}:8080"
spec:
  containers:
  - image: ${pod_container_image_uri}
    name: ${pod_name}-c1
  dnsPolicy: ClusterFirst
  runtimeClassName: ${pod_runtimeclass}
EOF
}

generate_pod_yaml

run_pod () {
  echo "[Run Pod]"
  kubectl delete -f ${pod_yaml} || true
  kubectl apply -f ${pod_yaml}
}

run_pod
